package com.zeng.plugin.createmodule;

import com.zeng.plugin.util.FreeMarkUtil;
import com.zeng.plugin.util.HumpStringUtil;
import com.zeng.plugin.util.cmd.CmdUtil;
import freemarker.template.TemplateException;
import org.apache.commons.io.IOUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.*;

@Mojo(name = "createModule")
public class CreateModuleMojo extends AbstractMojo {

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {

        CmdUtil cmdUtil = new CmdUtil();

        String parentGroupId = null;
        String parentArtifactId = null;


        /*
         * happy-pl-core-api
         * happy-pl-core-service
         * happy-pl-core-restful
         * happy-pl-core-admin
         * happy-pl-core-mobile
         *
         *
         *
         *
         * */
        parentGroupId = cmdUtil.print("请输入groupId (com.zhku.zeng):");
        if (StringUtils.isEmpty(parentGroupId)) {
            parentGroupId = "com.zhku.zeng";
        }

        this.getLog().info(String.format("parentGroupId:[%s]", parentGroupId));
        parentArtifactId = cmdUtil.print("请输入artifactId (vue-serve):");


        if (StringUtils.isEmpty(parentArtifactId)) {
            parentArtifactId = "vue-serve";
        }
        this.getLog().info(String.format("parentArtifactId:[%s]", parentArtifactId));

//        String restfulArtifactId = "vue-serve-restful";
//        默认 artifact id 就是模块名和目录名
        this.getLog().info(String.format("正在初始化模块名和目录名"));
        String restfulArtifactId = parentArtifactId + "-restful";
        this.getLog().info(String.format("restful模块 的目录名和模块名[%s]", restfulArtifactId));
        String apiArtifactId = parentArtifactId + "-api";
        this.getLog().info(String.format("api模块 的目录名和模块名[%s]", apiArtifactId));

        String serviceArtifactId = parentArtifactId + "-service";
        this.getLog().info(String.format("service模块 的目录名和模块名[%s]", serviceArtifactId));
        List<String> modules = new ArrayList<String>();
        modules.add(restfulArtifactId);
        modules.add(apiArtifactId);
        modules.add(serviceArtifactId);

//        String apiPackage = "com.zhku.zeng.vueserve.apimodule";
//        String servicePackage = "com.zhku.zeng.vueserve.servicemodule";
//        String restfulPackage = "com.zhku.zeng.vueserve.restfulmodule";
        String apiPackage = (parentGroupId + "." + parentArtifactId + ".apimodule").replace("-", "");
        String servicePackage = (parentGroupId + "." + parentArtifactId + ".servicemodule").replace("-", "");
        String restfulPackage = (parentGroupId + "." + parentArtifactId + ".restfulmodule").replace("-", "");

//        创建模块目录
        List<String> artifactIds = new ArrayList<String>();
        artifactIds.add(restfulArtifactId);
        artifactIds.add(apiArtifactId);
        artifactIds.add(serviceArtifactId);
        List<File> modulesDirs = createModulesDirs(new File("./" + parentArtifactId), artifactIds);
        File serviceJavaPath = modulesDirs.get(2);
        File restfulJavaPath = modulesDirs.get(0);

        //创建pom文件

        //设置模板文件
        List<String> templates = new ArrayList<>();
        templates.add("parent-pom.ftl");
        templates.add("restful-pom.ftl");
        templates.add("api-pom.ftl");
        templates.add("service-pom.ftl");

        try {
//            创建pom文件
            FreeMarkUtil freeMarkUtil = new FreeMarkUtil(templates);
            // 渲染模板数据
            Map<String, Object> data = new HashMap<>();
            data.put("modules", modules);
            data.put("parent_groupId", parentGroupId);
            data.put("parent_artifactId", parentArtifactId);
            data.put("service_module", serviceArtifactId);
            data.put("api_module", apiArtifactId);
            data.put("restful_module", restfulArtifactId);
            data.put("service_package", servicePackage);
            data.put("api_package", apiPackage);
            data.put("restful_package", restfulPackage);
            File parentArtifactIdDir = new File(parentArtifactId);
            File serviceArtifactIdDir = new File(parentArtifactId, serviceArtifactId);
            File apiArtifactIdDir = new File(parentArtifactId, apiArtifactId);
            File restfulArtifactIdDir = new File(parentArtifactId, restfulArtifactId);
            this.createFile(freeMarkUtil, templates.get(0), parentArtifactIdDir, data, "pom.xml");
            this.createFile(freeMarkUtil, templates.get(1), restfulArtifactIdDir, data, "pom.xml");
            this.createFile(freeMarkUtil, templates.get(2), apiArtifactIdDir, data, "pom.xml");
            this.createFile(freeMarkUtil, templates.get(3), serviceArtifactIdDir, data, "pom.xml");

        } catch (Exception e) {
            this.getLog().error(e.getMessage());
        }

        //创建tables 的目录和xml模板
        File template = new File(parentArtifactId, "template");
        if (!template.exists()) {
            template.mkdirs();
        }
        BufferedWriter output = null;
        try {
            output = new BufferedWriter(new FileWriter(new File(template, "tables.xml")));
            IOUtils.copy(this.getClass().getClassLoader().getResourceAsStream("tables.ftl"), output);
        } catch (IOException e) {
            this.getLog().error(e.getMessage());
        } finally {
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    this.getLog().error(e.getMessage(), e);
                }

            }
        }

        //创建annotaion 和 config

        Map<String, Object> serviceAnnotation = new HashMap<>();
        serviceAnnotation.put("package", servicePackage);
        serviceAnnotation.put("moduleHum", HumpStringUtil.humpStringHandle(serviceArtifactId, "-"));

        Map<String, Object> restfulAnnotation = new HashMap<>();
        restfulAnnotation.put("package", restfulPackage);
        restfulAnnotation.put("moduleHum", HumpStringUtil.humpStringHandle(restfulArtifactId, "-"));
        restfulAnnotation.put("service_moduleHum", serviceAnnotation.get("moduleHum"));
        restfulAnnotation.put("service_package", serviceAnnotation.get("package"));

        try {
            FreeMarkUtil freeMarkUtil = new FreeMarkUtil(Arrays.asList(new String[]{"annotation.ftl", "restful-config.ftl", "service-config.ftl"}));

            this.createFile(freeMarkUtil, "annotation.ftl",
                    new File(serviceJavaPath, servicePackage.replace(".", "/") + "/annotation"),
                    serviceAnnotation,
                    "Enable" + serviceAnnotation.get("moduleHum") + ".java");
            this.createFile(freeMarkUtil, "service-config.ftl",
                    new File(serviceJavaPath, servicePackage.replace(".", "/") + "/configuration"),
                    serviceAnnotation,
                    serviceAnnotation.get("moduleHum") + "Config.java");

            this.createFile(freeMarkUtil, "annotation.ftl",
                    new File(restfulJavaPath, restfulPackage.replace(".", "/") + "/annotation"),
                    restfulAnnotation,
                    "Enable" + restfulAnnotation.get("moduleHum") + ".java");
            this.createFile(freeMarkUtil, "restful-config.ftl",
                    new File(restfulJavaPath, restfulPackage.replace(".", "/") + "/configuration"),
                    restfulAnnotation,
                    restfulAnnotation.get("moduleHum") + "Config.java");
        } catch (Exception e) {
            this.getLog().error(e.getMessage());
        }

        //创建application
        try {
            FreeMarkUtil freeMarkUtil = new FreeMarkUtil(Collections.singletonList("application.ftl"));
            this.createFile(freeMarkUtil, "application.ftl",
                    new File(restfulJavaPath, restfulPackage.replace(".", "/")),restfulAnnotation,restfulAnnotation.get("moduleHum")+"Application.java");
        } catch (Exception e) {
            this.getLog().error(e.getMessage());

        }

        File restfulResPath = new File(restfulJavaPath.getAbsolutePath() + "/../resources");

        //复制配置文件
        this.copyClassPathRes(restfulResPath,"properties/application.properties");
        this.copyClassPathRes(restfulResPath,"properties/application-dev.properties");
        this.copyClassPathRes(restfulResPath,"properties/application-prod.properties");


    }

    public List<File> createModulesDirs(File rootDir, List<String> artifactids) {
        if (!rootDir.exists()) {
            rootDir.mkdirs();
        }
        List<File> moduleRoot = new ArrayList<>();

        for (String artifactid : artifactids) {
            File moduleDir = new File(rootDir, artifactid);
//            src - > main -> java| resources
            File javaPath = new File(moduleDir, "src/main/java");
            File resourcesPath = new File(moduleDir, "src/main/resources");
            if (!javaPath.exists()) {
                javaPath.mkdirs();
            }
            if (!resourcesPath.exists()) {
                resourcesPath.mkdirs();
            }
            moduleRoot.add(javaPath);
        }
        return moduleRoot;
    }

    public void createFile(FreeMarkUtil freeMarkUtil, String template, File root, Map<String, Object> data, String targetName) throws IOException, TemplateException {
        if (!root.exists()) {
            root.mkdirs();
        }
        File fileName = new File(root, targetName);
        freeMarkUtil.parse(template, fileName, data);

    }

    public void copyClassPathRes(File des, String classPathRes) {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(classPathRes);
        String[] split = classPathRes.split("/");
        BufferedWriter bufferedWriter = null;

        try {
            bufferedWriter = new BufferedWriter(new FileWriter(new File(des, split[split.length - 1])));
            IOUtils.copy(resourceAsStream,bufferedWriter);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }


    }

    public static void main(String[] args) throws IOException {
        String s = "a.b.c.d";
        String b = "e.f.g";
        File file = new File(s, b);
        System.out.println(file.getAbsolutePath());
        InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("properties/application.properties");
        System.out.println(IOUtils.toString(resourceAsStream, "utf8"));

    }
}
